/*
 * flash.h
 *
 * Created: 7/11/2013 12:02:47 PM
 *  Author: Tim
 */ 


#ifndef FLASH_H_
#define FLASH_H_

#include <inttypes.h>

#include "../features/adc/adc.h"

#define STSRG_BUSY_msk		0x01
#define	STSRG_WEL_msk		0x02
#define	STSRG_BP0_msk		0x04
#define	STSRG_BP1_msk		0x08
#define	STSRG_BP2_msk		0x10
#define	STSRG_TB_msk		0x20
#define	STSRG_R_msk			0x40
#define	STSRG_SRP_msk		0x80

#define writeEnable_cmd		0x06
#define writeEnableVol_cmd	0x50
#define writeDisable_cmd	0x04
#define readStatusReg_cmd	0x05
#define writeStatusReg_cmd	0x01
#define readData_cmd		0x03
#define pageProgram_cmd		0x02

#define chipErase_cmd		0x60

#define adcCh0FlashBaseAddr	0x000000	//1st 128k
#define adcCh1FlashBaseAddr	0x020000	//2nd 128k
#define adcCh2FlashBaseAddr	0x040000	//3rd 128k
#define adcCh3FlashBaseAddr	0x060000	//4th 128k

#define pagesPer128kB		512
#define sampleBufferSize	128

typedef union _2Byte{
	uint16_t	word;		//word
	struct BYTES{
		uint8_t	L ;		//low byte
		uint8_t	H ;		//high byte
	}bytes;
}u16b2_t;

typedef struct FLASH{
	
	uint32_t	baseAddr;
	uint32_t	curAddr;
	uint32_t	finAddr;
	
	uint16_t	numSamples;
	
	uint8_t		numChannels;
	uint8_t		addrInc;
	
	struct decode
	{
		uint8_t fCh0	:2;
		uint8_t fCh1	:2;
		uint8_t fCh2	:2;
		uint8_t fCh3	:2;		
	}adcChAlloc;
	
}flash_t;

flash_t flash;


void	spiInit();
void	chipErase();
uint32_t flashGetData(uint32_t address, uint8_t channel,uint16_t *channelData);
void readPage(uint16_t *buffer, uint32_t address);


//inline functions
static inline void	flashSel()
{
	PORTC.OUTCLR = 0x10;
}

static inline void	flashDeSel()
{
	PORTC.OUTSET = 0x10;
}

static inline void	spiWrite(uint8_t writeData)
{
	uint8_t temp;
	while(SPIC.STATUS & SPI_IF_bm);
	SPIC.DATA = writeData;
	while(!(SPIC.STATUS & SPI_IF_bm));
	temp = SPIC.DATA;
}

static inline uint8_t	spiRead()
{
	uint8_t temp;
	SPIC.DATA = 0x0;
	while(!(SPIC.STATUS & SPI_IF_bm));
	temp = SPIC.DATA;
	return temp;
}

static inline uint8_t readStatusReg()
{
	uint8_t temp;
	flashSel();
	spiWrite(readStatusReg_cmd);
	temp = spiRead();
	flashDeSel();
	return temp;
}

static inline void writeEnable()
{
	flashSel();
	spiWrite(writeEnable_cmd);
	flashDeSel();
}

#endif /* FLASH_H_ */